home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Packmags
/
Source, The - Issue 5 (1993)(Epsilon)[WB].zip
/
Source, The - Issue 5 (1993)(Epsilon)[WB].adf
/
Source
/
Vectors
/
sirds.lha
/
sirds.c
next >
Wrap
C/C++ Source or Header
|
1993-04-12
|
9KB
|
245 lines
/*******************************************************************/
/* */
/* sirds.c - by Henry Watson - Mar. 30, 1993 */
/* */
/* This program takes an input image in depth map format and */
/* generates a Single Image Random Dot Stereogram (SIRDS) image */
/* as output. Two fusion triangles are printed out at the top of */
/* the image to aid in seeing the hidden 3-D image. The number */
/* of disparity levels to be generated in the output image may */
/* also be specified but defaults to 11. */
/* */
/* =============================================================== */
/* */
/* To run, do */
/* % sirds <input_image> <output_image> [disparity_levels] */
/* */
/*******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <hipl_format.h> /* include HIPS definitions */
#include <math.h>
#define NODEBUG 0
#define DEBUG 1
#define PIXEL_FORMAT PFBYTE /* set the pixel format for the HIPS routines */
typedef byte PIXEL_TYPE; /* set the pixel type for the program to use */
#define NUM_GRAY_LEVELS 256
#define WHITE (PIXEL_TYPE)255
#define BLACK (PIXEL_TYPE)0
#define MAXSIZE 512 /* maximum dimension to image array */
/* and thus input image as well */
#define IMAGE_OFFSET_PCT 0.30 /* stereo image offset in terms of percent */
#define MAXSIRDSWIDTH 665 /* maximum width of final SIRDS image */
/* MAXSIZE * (IMAGE_OFFSET_PCT+1) */
#define DOTHEIGHT 9 /* height of the fusion dots at the page top */
#define DISPARITY_LEVELS 11 /* default number of discrete levels of */
/* disparity. Ranges from -d/2 to 0 to +d/2 */
/* (ie. number of levels of depth) */
#define frame_number 1 /* constant frame number for HIPS routines */
/*******************************************************************/
/* main() */
/* */
/* The sequence of processing steps involves: */
/* (1) interpreting the command line */
/* (2) reading the header */
/* (3) validating the input size, format, etc. */
/* (4) reading image frame */
/* (5) performing image processing algorithms */
/* (6) forming the output image */
/* (7) writing to file */
/* */
/*******************************************************************/
void main( argc, argv )
int argc;
char **argv;
{
char *input_filename, *output_filename;
FILE *input_fp, *output_fp;
struct header input_header, output_header;
PIXEL_TYPE Object[MAXSIZE][MAXSIZE],
Sirds[MAXSIZE][MAXSIRDSWIDTH];
byte *pixel_ptr;
int rowmax, colmax,
row, col,
right_image_start,
sirdswidth, sirdsheight,
disparity_levels = DISPARITY_LEVELS,
disparity_offset = DISPARITY_LEVELS/-2,
disparity;
/* INTERPRETING THE COMMAND LINE */
if( (argc<3) || (argc>4) )
{
printf("Usage: %s <input_image> <output_image> [disparity_levels]\n", argv[0]);
exit(0);
}
input_filename = argv[1]; /* name of input file */
output_filename = argv[2]; /* name of output file */
if( argc>3 )
{
disparity_levels = atoi( argv[3] );
disparity_offset = disparity_levels/-2;
if( disparity_levels < 2 )
{
printf("Invalid number of disparity levels specified.\n");
printf("Value must be 2 or greater. Default is %d.\n",
DISPARITY_LEVELS);
exit(-1);
}
}
/* READING THE HEADER */
/* open the file and read header */
input_fp = hfopenr( input_filename );
fread_hdr_a( input_fp, &input_header, input_filename );
/* copy image x and y dimensions */
rowmax = input_header.orows;
colmax = input_header.ocols;
/* VALIDATING THE INPUT SIZE, FORMAT, ETC. */
if( input_header.pixel_format != PIXEL_FORMAT )
{
printf("This program only handles pixel format %d.\n",PIXEL_FORMAT);
printf("Program aborted.\n");
exit(-1);
}
else if( rowmax>MAXSIZE || colmax>MAXSIZE )
{
printf("Input image too large. Maximum size is %d X %d.\n",MAXSIZE,MAXSIZE);
exit(-1);
}
else
{
printf("%d X %d %s is being read.\n", rowmax, colmax, input_filename);
}
/* READING IMAGE FRAME */
/* read the image frame into a buffer */
fread_image( input_fp, &input_header, frame_number, input_filename );
/* reformat the buffer into an array; */
/* image is pointed to by input_header.image */
pixel_ptr = input_header.image;
for( row=0; row < rowmax; row++ )
{
pixel_ptr = input_header.image + (row*colmax*input_header.sizepix);
for( col=0; col < colmax; col++ )
Object[row][col] = (PIXEL_TYPE) *pixel_ptr++;
}
/* PERFORMING IMAGE PROCESSING ALGORITHM */
/* determine the right stereo image position and the final image size */
right_image_start = IMAGE_OFFSET_PCT * colmax;
sirdswidth = colmax + right_image_start;
sirdsheight = rowmax;
/* fill the SIRDS image with random binary values */
for( row=0; row < sirdsheight; row++ )
for( col=0; col < sirdswidth; col++ )
Sirds[row][col] = ( (rand() > RAND_MAX/2) ? WHITE : BLACK );
/* perform pixel shifts based on input Object image */
for( row=0; row < rowmax; row++ )
for( col=0; col < colmax; col++ )
{
/* assign high (+d) disparity to low intensities (ie. dark = far) */
/* and low disparity (-d) to high intensities (ie. bright = near) */
disparity = (NUM_GRAY_LEVELS-Object[row][col]-1) * disparity_levels
/ NUM_GRAY_LEVELS + disparity_offset;
/* make sure the destination pixel position is in range */
if( right_image_start+col+disparity < sirdswidth )
Sirds[row][right_image_start+col+disparity] = Sirds[row][col];
}
/* FORMING THE OUTPUT IMAGE */
/* initialize a header from scratch and allocate an image for the header */
init_hdr_alloc( &output_header, "", "", frame_number, "",
sirdsheight+DOTHEIGHT, sirdswidth, PIXEL_FORMAT, 1, "");
/* output_header - address of the HIPS header */
/* "" - original sequence name for documentation purposes */
/* "" - new sequence name for documentation purpose */
/* frame_number - only one frame is required here */
/* "" - date for documentation purposes */
/* sirdsheight - number of rows */
/* sirdswidth - number of columns */
/* PIXEL_FORMAT - code for pixel format */
/* 1 - number of color planes */
/* "" - the sequence description for documentation purpose */
/* write the image array to the output header */
pixel_ptr = output_header.image;
/* first write out a pair of fusion dots for ease of viewing */
/* (ie. generate the two funky looking triangles at the top) */
for( row=0; row < DOTHEIGHT; row++ )
for( col=0; col < sirdswidth; col++ )
if( ( col>=(colmax/2-DOTHEIGHT+1+row)
&& col<=(colmax/2+DOTHEIGHT-1-row) )
|| ( col>=(right_image_start+colmax/2-DOTHEIGHT+1+row)
&& col<=(right_image_start+colmax/2+DOTHEIGHT-1-row) ) )
*pixel_ptr++ = (byte) BLACK;
else
*pixel_ptr++ = (byte) WHITE;
/* second, write out the SIRDS array */
for( row=0; row < sirdsheight; row++ )
for( col=0; col < sirdswidth; col++ )
*pixel_ptr++ = (byte) Sirds[row][col];
/* WRITE TO FILE */
printf("%d X %d %s is being written.\n", sirdsheight, sirdswidth,
output_filename);
output_fp = ffopen( output_filename, "w" );
fwrite_header( output_fp, &output_header, output_filename );
fwrite_image( output_fp, &output_header, 1, output_filename );
fclose( output_fp );
}